; FLoating File System API module (int 32h)
; Only headers & general info yet.
int32h_handler:

	push	int32h_end	; used to return from functions using 'ret'
			; to allow cross-function CALLing
	; AH = function number
	cmp	ah,	0h		; function 0h - resolve entry address (find file/dir)
	je	i32_0
	cmp	ah,	1h		; function 1h - get entry type
	je	i32_1
	cmp	ah,	2h		; function 2h - open file
	je	i32_2
	cmp	ah,	3h		; function 3h - seek file
	je	i32_3
	cmp	ah,	4h		; function 4h - read file sector
	je	i32_4
	cmp	ah,	5h		; function 5h - close file
	je	i32_5
	cmp	ah,	10h		; function 10h - read LBA sector
	je	i32_10
	cmp	ah,	77h		; function 10h - read LBA sector
	je	i32_77

	ret

; AH=77: print file system (just for test)
	i32_77:
		mov	cx,	100	; counter; TODO: should be dynamic later

		mov	edx,	00000000h
		mov	ebx,	000000FFh	; pre-start of root fs
		mov	si,	i32_node
	.rep:	inc	ebx
		call	i32_10

		test	node_type(i32_node),	11b
		jz	.not

		push	si
		mov	ah,	1h
		mov	si,	node_data(i32_node)
		int	30h
		mov	ah,	1h
		mov	si,	crlf
		int	30h
		pop	si
;		push	dx
;		xor	dx,	dx
;		mov	ah,	3
;		mov	dl,	[i32_node]
;		int	30h
;		pop	dx
	.not:	loop	.rep
		
		ret

; AH=0: reslove entry address
;	ES:BX - entry name-and-path buffer pointer
;		Examples:	@/home/somefile
;				@/system/testdir
; returns:
;	EBX..EDX - entry physical address (PA) (QWORD)
;	AL - return code:
;		0 - success
;		1 - wrong root
;		2 - file/path doesn't exist

	i32_0:

	call	parse_path

;	mov	ah,	1h
;	mov	si,	fname
;	int	30h
;	mov	ah,	1h
;	mov	si,	crlf
;	int	30h

	mov	edx,	00000000h
	mov	ebx,	00000100h	; @ (ROOT NODE) address
	mov	si,	i32_node
	call	i32_10

	mov	ah,	1h
	mov	si,	node_data(i32_node)
	int	30h

	_comp	node_data(i32_node),	rootnode

;	add	al,	100
	xor	ah,	ah
	mov	dx,	ax
	mov	ah,	3h
	int	30h		; print AL

	test	al,	al
	jz	.d_wrong_root

	jmp	.d_loop_start
;.d_loop:

.d_loop_start:
	call	read_child	; go down one level
	call	parse_path
	jmp	.d_ent

.d_nxt:
		mov	ah,	3h
		mov	dx,	1337d
		int	30h
	call	_comp8		; check if there are still NEXTs:
	test	al,	al	; if not,
	je	.d_not_found	; return 2
	call	read_next
	call	parse_path

.d_ent:	
	_comp	node_data(i32_node),	fname
	test	al,	al
;	jnz	.d_loop	; go down one level
	jz	.d_found
	jmp	.d_nxt



.d_found:
;	mov	edx,	dword [node_addr]
;	mov	ebx,	dword [node_addr+4]
	mov	al,	0
	ret

.d_wrong_root:
	mov	al,	1
	ret

.d_not_found:
	mov	al,	2
	ret

;	xor	ah,	ah
;	mov	dx,	ax
;	mov	ah,	3h
;	int	30h

;	test	al,	al
;	jnz	.again

	; Compare QWord node_next()
	_comp8:
		cmp	node_next_ms(i32_node),	dword 0h
		jne	failed
		cmp	node_next_ls(i32_node),	dword 0h
		jne	failed
		mov	al,	0
	ret
	failed:
		mov	al,	1
	ret

	; Read child element subfuction
	read_child:
		mov	edx,	node_child_ms(i32_node)
		mov	ebx,	node_child_ls(i32_node)
		mov	si,	i32_node
		call	i32_10
	ret

	; Read next (brother) element subfuction
	read_next:
		mov	edx,	node_next_ms(i32_node)
		mov	ebx,	node_next_ls(i32_node)
		mov	si,	i32_node
		call	i32_10
	ret

	; Path parsing subfunction
	; Takes:	EDX - path fragment address
	; Returns:	AL - is last? 1 or 0
	parse_path:
		push	ecx
		mov	ecx,	fname
;		mov	ah,	0h

		jmp	.r_sta

	.r_rep:	inc	edx
		inc	ecx
;		inc	ah

	.r_sta:	cmp	byte [edx],	'/'
		je	.r_end_notlast
		cmp	byte [edx],	0h
		je	.r_end_last
		mov	al,	byte [edx]
		mov	byte [ecx],	al
		jmp	.r_rep

	.r_end_notlast:
		mov	al,	1		; return 1 if there are still elements in string
		inc	edx
		jmp	.r_end
	.r_end_last:
		mov	al,	0		; return 0 if we're done
	.r_end:
		mov	byte [ecx],	0h	; add string end

		pop	ecx
	ret



		mov	cx,	100	; counter; TODO: should be dynamic later

		mov	edx,	00000000h
		mov	ebx,	000000FFh	; pre-start of root fs
		mov	si,	i32_node
	.rep:	inc	ebx
		call	i32_10

		test	node_type(i32_node),	11b
		jz	.not

		push	si
		mov	si,	node_data(i32_node)
		mov	ah,	1h
		int	30h
		mov	ah,	1h
		mov	si,	crlf
		int	30h
		pop	si
;		push	dx
;		xor	dx,	dx
;		mov	ah,	3
;		mov	dl,	[i32_node]
;		int	30h
;		pop	dx
	.not:	loop	.rep
		
		ret

; AH=1: get entry type
;	EDX..EAX - entry PA
; returns:
;	AL - entry type:
;		bits 1..0: 00 - dir, 01 - file, 1x - root node

	i32_1:
		ret

; AH=2: open file (append handle to file handles and set file pointer)
;	EDX..EBX - file PA
; returns:
;	AX - file handle (for use with read/write)

	i32_2:
		ret

; AH=3: seek file
;	EAX - seek position

	i32_3:
		ret

; AH=4: read file sector
;	CX - file handle
; returns:
;	ES:BX - file data sector (240 bytes)
;	DX - number of bytes read

	i32_4:
		ret

; AH=5: close file
;	AX - file handle

	i32_5:
		ret

; AH=10h: Read sector by DAP using LBA
;	EDX...EBX - logical sector number (LBA)
;	ds:si - address where to place sector data

	i32_10:
		pusha
		mov     [word lba_dap+4],	si
		mov	[word lba_dap+6],	ds
		mov	[dword lba_dap+8],	ebx
		mov	[dword lba_dap+12],	edx
		mov	ah,	42h
		mov	dl,	[disknum]
		mov	si,	lba_dap
		int	13h
		popa
;		jmp	.iend
		ret

; interrupt ends here
	int32h_end:
iret

; data
	lba_dap	db	10h	; used by function int32h:10h
		db	0h
		dw	1h
		dw	0h		; sector offset (sector)
		dw	0h	; sector segment (KERNEL_ENTRY)
		dq	00000000h	; what sector to read?

	i32_node:	istruc	FLFS_Node
;		at	FLFS_Node.data,	db	0
;		at	FLFS_Node.data,	db	0xC3
	iend

	fname	times	256	db	0	; place to store returned path fragment
	rootnode	db	'@',0

	node_addr	times	2	dd	0
